﻿using Microsoft.AspNetCore.StaticFiles;

using System.Buffers.Text;
using System.Text;

using static System.Net.Mime.MediaTypeNames;

namespace anydata.Extensions
{
    public static class StringExtrensions
    {
        private const string BASE32 = "abcdefghijklmnopqrsuvwxyz1235689";

        public static string ToBase32(this string from)
        {
            var value = Encoding.UTF8.GetBytes(from);
            int length = (value.Length * 8 + 4) / 5;
            StringBuilder sb = new StringBuilder(length);
            int cur_i = 0;
            byte cur_b = 0;
            int index;
            int k;
            for (int i = 0; i < length; i++)
            {
                index = 0;
                for (int j = 0; j < 5; j++)
                {
                    k = i * 5 + j;
                    if (k == value.Length * 8)
                        break;
                    if (k % 8 == 0)
                        cur_b = value[cur_i++];
                    index <<= 1;
                    index |= (cur_b & 128) == 0 ? 0 : 1;
                    cur_b <<= 1;
                }
                sb.Append(BASE32[index]);
            }
            return "t" + sb.ToString();
        }

        public static string FromBase32(this string to)
        {
            var value = to.ToLower().Replace("t", "");
            int length = value.Length * 5 / 8;
            byte[] r = new byte[length];
            int cur_i = 0;
            int cur_v = 0;
            int k;
            for (int i = 0; i < length; i++)
            {
                for (int j = 0; j < 8; j++)
                {
                    k = i * 8 + j;
                    if (k == value.Length * 5)
                        break;
                    if (k % 5 == 0)
                    {
                        cur_v = BASE32.IndexOf(value[cur_i++]);
                        if (cur_i == value.Length && value.Length % 8 != 0)
                            cur_v <<= value.Length * 5 % 8;
                    }
                    r[i] <<= 1;
                    r[i] |= (byte)((cur_v & 16) == 0 ? 0 : 1);
                    cur_v <<= 1;
                }
            }
            return Encoding.UTF8.GetString(r);
        }
        public static string Random32(this string source, int length)
        {
            var result = "";
            var rm = new Random();
            while(length-- > 0)
            {
                result += BASE32[rm.Next(31)];
            }
            return result + source.ToBase32();
        }
        public static string ToBase64(this string from)
        {
            if (string.IsNullOrWhiteSpace(from)) return from;
            var r = Encoding.UTF8.GetBytes(from);
            return Convert.ToBase64String(r);
        }
        public static string FromBase64(this string to)
        {
            if (string.IsNullOrWhiteSpace(to)) return to;
            var r = Convert.FromBase64String(to.Replace(' ','+'));
            return Encoding.UTF8.GetString(r);
        }
        public static string ContentType(this string extension, bool smp4 = true)
        {
            extension = string.IsNullOrWhiteSpace(extension) ? "" : extension;
            if (extension.ToLower().EndsWith("smp4"))
            {
                return smp4 ? "video/stream" : "text/plain";
            }
            var provider = new FileExtensionContentTypeProvider();
            if (provider.Mappings.TryGetValue(extension, out var contentType))
            {
                return contentType;
            }
            return "application/octet-stream";
        }
    }
}
